package services

import (
	"context"
	"errors"
	"feng-che.com/server/driver-quiz/internal/constants"
	"feng-che.com/server/driver-quiz/internal/dep_db"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/bson/primitive"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"mongoDB"
	"time"
)

// ServiceSold 这个是平台可以出售的服务信息
type ServiceSold struct {
	mongoDB.MongoDefaultModelNonID `bson:"basic"`
	ID                             primitive.ObjectID `bson:"_id,omitempty" json:"id"`
	OriginServiceID                primitive.ObjectID `bson:"origin_service_id" json:"originServiceID"` // 原始服务ID
	OriginService                  `bson:"origin_service" json:"OriginService"`
	ClientID                       primitive.ObjectID `bson:"client_id" json:"clientID"`     // 购买用户ID
	Used                           bool               `bson:"used" json:"used"`              // 是否使用过
	UsedTime                       time.Time          `bson:"used_time" json:"usedTime"`     // 使用时间
	Canceled                       bool               `bson:"canceled" json:"canceled"`      // 是否取消-不可用
	CancelTime                     time.Time          `bson:"cancel_time" json:"cancelTime"` // 取消时间
	ProfitSharing                  `json:"profitSharing" bson:"profit_sharing"`
	// 支付成功后修改的值
	SoldTime  time.Time          `bson:"sold_time" json:"soldTime"`   // 出售时间
	PaymentID primitive.ObjectID `bson:"payment_id" json:"paymentID"` // 对应的支付ID
}

type OriginService struct {
	Name          string                  `json:"name" bson:"name"`
	Description   string                  `json:"description" bson:"-"`
	ExamCourse    constants.ExamCourse    `json:"examCourse" bson:"examCourse"`                   // 考试科目
	InstitutionID primitive.ObjectID      `bson:"institution_id,omitempty" json:"institution_id"` // 模拟考场机构ID
	Nature        constants.ServiceNature `json:"nature" bson:"nature"`                           // 服务类型,用来合适服务是否适用
	Price         int                     `json:"price" bson:"price"`
	Duration      int                     `json:"duration" bson:"duration"` // 服务时长，单位分钟
}

func (s *Service) ToOriginService() OriginService {
	return OriginService{
		Name:          s.Name,
		Description:   s.Description,
		ExamCourse:    s.ExamCourse,
		InstitutionID: s.InstitutionID,
		Nature:        s.Nature,
		Price:         s.Price,
		Duration:      s.Duration,
	}
}

func (some *ServiceSold) Save(ctx context.Context, updateOptions ...*options.UpdateOptions) (*mongo.UpdateResult, error) {
	if some.ID.IsZero() {
		some.ID = primitive.NewObjectID()
	}
	var opts []*options.UpdateOptions
	if len(updateOptions) > 0 && updateOptions[0] != nil {
		opts = updateOptions
	} else {
		opts = append(opts, options.Update().SetUpsert(true))
	}
	result, err := some.GetCollection().UpdateByID(ctx, some.ID, bson.D{
		{"$set", some},
	}, opts...)
	return result, err
}

func (some *ServiceSold) Update(ctx context.Context, dataFields *bson.D, opts ...*options.UpdateOptions) error {
	if some.ID.IsZero() {
		return errors.New("没有带入id")
	}
	*dataFields = append(*dataFields, bson.E{Key: "$set", Value: bson.D{*mongoDB.CommonUpdateTimeFieldWithCurrentTime()}})
	_, err := some.GetCollection().UpdateByID(ctx, some.ID, *dataFields, opts...)
	return err
}

func (some *ServiceSold) Delete(ctx context.Context) error {
	if some.ID.IsZero() {
		return errors.New("没有带入id")
	}
	delFiled := bson.D{}
	fields := mongoDB.CommonDeleteWriteFields()
	for _, i2 := range *fields {
		delFiled = append(delFiled, i2)
	}
	return some.Update(ctx, &bson.D{
		{"$set", delFiled},
	})
}

func (some *ServiceSold) GetCollectionName() string {
	return "service_sold"
}

func (some *ServiceSold) GetCollection() *mongo.Collection {
	name := some.GetCollectionName()
	return dep_db.ObjectCollection(&name)
}

// NewServiceSold 创建一个出售的服务的唯一方法!
func NewServiceSold(service *Service) *ServiceSold {
	result := &ServiceSold{}
	result.OriginServiceID = service.ID
	result.OriginService = service.ToOriginService()
	result.Create()
	result.ID = primitive.NilObjectID
	result.ProfitSharing = service.ProfitSharing
	return result
}
